// import 'dart:math' as math;
// import 'dart:ui' as ui;

// import 'package:live_photo_detector/index.dart';

// class M7AndroidFaceDetectorPainter extends CustomPainter {
//   final FaceDetectionModel model;
//   final PreviewSize previewSize;
//   final Rect previewRect;
//   final bool isBackCamera;
//   final Color? detectionColor;
//   late DashedPathProperties _dashedPathProperties;

//   M7AndroidFaceDetectorPainter({
//     required this.model,
//     required this.previewSize,
//     required this.previewRect,
//     required this.isBackCamera,
//     this.detectionColor,
//   });

//   @override
//   void paint(Canvas canvas, Size size) {
//     _dashedPathProperties = DashedPathProperties(
//       path: Path(),
//       dashLength: 5.0,
//       dashGapLength: 2.5,
//     );
//     final croppedSize = model.croppedSize;

//     final ratioAnalysisToPreview = previewSize.width / croppedSize.width;

//     bool flipXY = false;
//     if (Platform.isAndroid) {
//       // Symmetry for Android since native image analysis is not mirrored but preview is
//       // It also handles device rotation
//       switch (model.imageRotation) {
//         case InputImageRotation.rotation0deg:
//           if (isBackCamera) {
//             flipXY = true;
//             canvas.scale(-1, 1);
//             canvas.translate(-size.width, 0);
//           } else {
//             flipXY = true;
//             canvas.scale(-1, -1);
//             canvas.translate(-size.width, -size.height);
//           }
//           break;
//         case InputImageRotation.rotation90deg:
//           if (isBackCamera) {
//             // No changes
//           } else {
//             canvas.scale(1, -1);
//             canvas.translate(0, -size.height);
//           }
//           break;
//         case InputImageRotation.rotation180deg:
//           if (isBackCamera) {
//             flipXY = true;
//             canvas.scale(1, -1);
//             canvas.translate(0, -size.height);
//           } else {
//             flipXY = true;
//           }
//           break;
//         default:
//           // 270 or null
//           if (isBackCamera) {
//             canvas.scale(-1, -1);
//             canvas.translate(-size.width, -size.height);
//           } else {
//             canvas.scale(-1, 1);
//             canvas.translate(-size.width, 0);
//           }
//       }
//     }

//     for (final Face face in model.faces) {
//       Map<FaceContourType, Path> paths = {
//         for (var fct in FaceContourType.values) fct: Path()
//       };
//       face.contours.forEach((contourType, faceContour) {
//         if (faceContour != null) {
//           paths[contourType]!.addPolygon(
//               faceContour.points
//                   .map(
//                     (element) => _croppedPosition(
//                       element,
//                       croppedSize: croppedSize,
//                       painterSize: size,
//                       ratio: ratioAnalysisToPreview,
//                       flipXY: flipXY,
//                     ),
//                   )
//                   .toList(),
//               true);
//           if (M7LivelynessDetection.instance.displayDots) {
//             for (var element in faceContour.points) {
//               canvas.drawCircle(
//                 _croppedPosition(
//                   element,
//                   croppedSize: croppedSize,
//                   painterSize: size,
//                   ratio: ratioAnalysisToPreview,
//                   flipXY: flipXY,
//                 ),
//                 4,
//                 Paint()
//                   ..color = detectionColor ??
//                       M7LivelynessDetection.instance.contourDotColor ??
//                       Colors.purple.shade800
//                   ..strokeWidth =
//                       M7LivelynessDetection.instance.contourDotRadius ?? 2,
//               );
//             }
//           }
//         }
//       });
//       paths.removeWhere((key, value) => value.getBounds().isEmpty);
//       if (M7LivelynessDetection.instance.displayLines) {
//         for (var p in paths.entries) {
//           final Path finalPath = M7LivelynessDetection.instance.displayDash
//               ? _getDashedPath(
//                   p.value,
//                   M7LivelynessDetection.instance.dashLength,
//                   M7LivelynessDetection.instance.dashGap,
//                 )
//               : p.value;
//           canvas.drawPath(
//             finalPath,
//             Paint()
//               ..color = detectionColor ??
//                   M7LivelynessDetection.instance.contourLineColor ??
//                   Colors.white
//               ..strokeWidth =
//                   M7LivelynessDetection.instance.contourLineWidth ?? 1.6
//               ..style = PaintingStyle.stroke,
//           );
//         }
//       }
//     }
//   }

//   @override
//   bool shouldRepaint(M7AndroidFaceDetectorPainter oldDelegate) {
//     return oldDelegate.isBackCamera != isBackCamera ||
//         oldDelegate.previewSize.width != previewSize.width ||
//         oldDelegate.previewSize.height != previewSize.height ||
//         oldDelegate.previewRect != previewRect ||
//         oldDelegate.model != model;
//   }

//   Offset _croppedPosition(
//     Point<int> element, {
//     required Size croppedSize,
//     required Size painterSize,
//     required double ratio,
//     required bool flipXY,
//   }) {
//     num imageDiffX;
//     num imageDiffY;
//     if (Platform.isIOS) {
//       imageDiffX = model.absoluteImageSize.width - croppedSize.width;
//       imageDiffY = model.absoluteImageSize.height - croppedSize.height;
//     } else {
//       imageDiffX = model.absoluteImageSize.height - croppedSize.width;
//       imageDiffY = model.absoluteImageSize.width - croppedSize.height;
//     }

//     return (Offset(
//               (flipXY ? element.y : element.x).toDouble() - (imageDiffX / 2),
//               (flipXY ? element.x : element.y).toDouble() - (imageDiffY / 2),
//             ) *
//             ratio)
//         .translate(
//       (painterSize.width - (croppedSize.width * ratio)) / 2,
//       (painterSize.height - (croppedSize.height * ratio)) / 2,
//     );
//   }

//   Path _getDashedPath(
//     Path originalPath,
//     double dashLength,
//     double dashGapLength,
//   ) {
//     final metricsIterator = originalPath.computeMetrics().iterator;
//     while (metricsIterator.moveNext()) {
//       final metric = metricsIterator.current;
//       _dashedPathProperties.extractedPathLength = 0.0;
//       while (_dashedPathProperties.extractedPathLength < metric.length) {
//         if (_dashedPathProperties.addDashNext) {
//           _dashedPathProperties.addDash(metric, dashLength);
//         } else {
//           _dashedPathProperties.addDashGap(metric, dashGapLength);
//         }
//       }
//     }
//     return _dashedPathProperties.path;
//   }
// }

// class DashedPathProperties {
//   double extractedPathLength;
//   Path path;

//   final double _dashLength;
//   double _remainingDashLength;
//   double _remainingDashGapLength;
//   bool _previousWasDash;

//   DashedPathProperties({
//     required this.path,
//     required double dashLength,
//     required double dashGapLength,
//   })  : assert(dashLength > 0.0, 'dashLength must be > 0.0'),
//         assert(dashGapLength > 0.0, 'dashGapLength must be > 0.0'),
//         _dashLength = dashLength,
//         _remainingDashLength = dashLength,
//         _remainingDashGapLength = dashGapLength,
//         _previousWasDash = false,
//         extractedPathLength = 0.0;

//   bool get addDashNext {
//     if (!_previousWasDash || _remainingDashLength != _dashLength) {
//       return true;
//     }
//     return false;
//   }

//   void addDash(ui.PathMetric metric, double dashLength) {
//     // Calculate lengths (actual + available)
//     final end = _calculateLength(metric, _remainingDashLength);
//     final availableEnd = _calculateLength(metric, dashLength);
//     // Add path
//     final pathSegment = metric.extractPath(extractedPathLength, end);
//     path.addPath(pathSegment, Offset.zero);
//     // Update
//     final delta = _remainingDashLength - (end - extractedPathLength);
//     _remainingDashLength = _updateRemainingLength(
//       delta: delta,
//       end: end,
//       availableEnd: availableEnd,
//       initialLength: dashLength,
//     );
//     extractedPathLength = end;
//     _previousWasDash = true;
//   }

//   void addDashGap(ui.PathMetric metric, double dashGapLength) {
//     // Calculate lengths (actual + available)
//     final end = _calculateLength(metric, _remainingDashGapLength);
//     final availableEnd = _calculateLength(metric, dashGapLength);
//     // Move path's end point
//     ui.Tangent tangent = metric.getTangentForOffset(end)!;
//     path.moveTo(tangent.position.dx, tangent.position.dy);
//     // Update
//     final delta = end - extractedPathLength;
//     _remainingDashGapLength = _updateRemainingLength(
//       delta: delta,
//       end: end,
//       availableEnd: availableEnd,
//       initialLength: dashGapLength,
//     );
//     extractedPathLength = end;
//     _previousWasDash = false;
//   }

//   double _calculateLength(ui.PathMetric metric, double addedLength) {
//     return math.min(extractedPathLength + addedLength, metric.length);
//   }

//   double _updateRemainingLength({
//     required double delta,
//     required double end,
//     required double availableEnd,
//     required double initialLength,
//   }) {
//     return (delta > 0 && availableEnd == end) ? delta : initialLength;
//   }
// }
